<!DOCTYPE html>
<html lang="en">

<!-- Head tag -->
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="description" content="A very lame cool person">
    <meta name="keyword" content="null">
    <meta name="theme-color" content="#600090">
    <meta name="msapplication-navbutton-color" content="#600090">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="#600090">
    <link rel="shortcut icon" href="/favicon.ico">
    <link rel="alternate" type="application/atom+xml" title="Guanghui" href="/atom.xml">
    <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
    <link rel="stylesheet" href="//cdn.bootcss.com/font-awesome/4.6.3/css/font-awesome.css">
    <title>
        
        angular2-chapter06 -- Collecting Data with Forms and Validation｜Guanghui&#39;s blog
        
    </title>

    <link rel="canonical" href="https://wghglory.github.io/2017/04/24/angular2-chapter06/">

    <!-- Bootstrap Core CSS -->
    <link rel="stylesheet" href="/css/bootstrap.min.css">

    <!-- Custom CSS -->
    <link rel="stylesheet" href="/css/blog-style.css">

    <link rel="stylesheet" href="/css/my.css">

    <!-- Pygments Github CSS -->
    <link rel="stylesheet" href="/css/syntax.css">
</head>

<style>

    header.intro-header {
        background-image: url('/images/tag.jpg')
    }
</style>
<!-- hack iOS CSS :active style -->
<body ontouchstart="" class="animated fadeIn">
<!-- Navigation -->
<nav class="navbar navbar-default navbar-custom navbar-fixed-top " id="nav-top" data-ispost = "true" data-istags="false
" data-ishome = "false" >
    <div class="container-fluid">
        <!-- Brand and toggle get grouped for better mobile display -->
        <div class="navbar-header page-scroll">
            <button type="button" class="navbar-toggle">
                <span class="sr-only">Toggle navigation</span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
                <span class="icon-bar"></span>
            </button>
            <a class="navbar-brand animated pulse" href="/">
                <span class="brand-logo">
                    Guanghui
                </span>
                's Blog
            </a>
        </div>

        <!-- Collect the nav links, forms, and other content for toggling -->
        <!-- Known Issue, found by Hux:
            <nav>'s height woule be hold on by its content.
            so, when navbar scale out, the <nav> will cover tags.
            also mask any touch event of tags, unfortunately.
        -->
        <!-- /.navbar-collapse -->
        <div id="huxblog_navbar">
            <div class="navbar-collapse">
                <ul class="nav navbar-nav navbar-right">
                    <li>
                        <a href="/">Home</a>
                    </li>
					
                    
                        
							
                        <li>
                            <a href="/tags/">tags</a>
                        </li>
							
						
                    
                        
							
                        <li>
                            <a href="/works/">my works</a>
                        </li>
							
						
                    

					
                        <li>
                            <a href="https://wghglory.github.io/guanghui.resume/" target="_blank">Resume</a>
                        </li>
                </ul>
            </div>
        </div>
    </div>
    <!-- /.container -->
</nav>
<script>
    // Drop Bootstarp low-performance Navbar
    // Use customize navbar with high-quality material design animation
    // in high-perf jank-free CSS3 implementation
//    var $body   = document.body;
    var $toggle = document.querySelector('.navbar-toggle');
    var $navbar = document.querySelector('#huxblog_navbar');
    var $collapse = document.querySelector('.navbar-collapse');

    $toggle.addEventListener('click', handleMagic)
    function handleMagic(e){
        if ($navbar.className.indexOf('in') > 0) {
        // CLOSE
            $navbar.className = " ";
            // wait until animation end.
            setTimeout(function(){
                // prevent frequently toggle
                if($navbar.className.indexOf('in') < 0) {
                    $collapse.style.height = "0px"
                }
            },400)
        }else{
        // OPEN
            $collapse.style.height = "auto"
            $navbar.className += " in";
        }
    }
</script>

<!-- Main Content -->

<!--only post-->


<img class="wechat-title-img" src="/images/default-post.jpg">


<style>
    
    header.intro-header {
        background-image: url('/images/default-post.jpg');
    }

    
</style>

<header class="intro-header">
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1 text-center">
                <div class="post-heading">
                    <h1>angular2-chapter06 -- Collecting Data with Forms and Validation</h1>
                    
                    <span class="meta">
                         作者 Guanghui Wang
                        <span>
                          日期 2017-04-24
                         </span>
                    </span>
                    <div class="tags text-center">
                        
                        <a class="tag" href="/tags/#Angular2"
                           title="Angular2">Angular2</a>
                        
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="post-title-haojen">
        <span>
            <!-- angular2-chapter06 -- Collecting Data with Forms and Validation -->
        </span>
    </div>
</header>

<!-- Post Content -->
<article>
    <div class="container">
        <div class="row">
            <!-- Post Container -->
            <div class="col-lg-8 col-lg-offset-1 col-sm-9 post-container">
                <h1 id="Collecting-Data-with-Forms-and-Validation"><a href="#Collecting-Data-with-Forms-and-Validation" class="headerlink" title="Collecting Data with Forms and Validation"></a>Collecting Data with Forms and Validation</h1><p>Check code at: <a href="https://github.com/wghglory/angular2-fundamental" target="_blank" rel="noopener">https://github.com/wghglory/angular2-fundamental</a></p>
<h3 id="Using-Models-for-Type-Safety"><a href="#Using-Models-for-Type-Safety" class="headerlink" title="Using Models for Type Safety"></a>Using Models for Type Safety</h3><p>1) create events/shared/event.model.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> interface IEvent &#123;</span><br><span class="line">    id: number</span><br><span class="line">    name: string</span><br><span class="line">    date: <span class="built_in">Date</span></span><br><span class="line">    time: string</span><br><span class="line">    price: number</span><br><span class="line">    imageUrl: string</span><br><span class="line">    location?: &#123;</span><br><span class="line">        address: string</span><br><span class="line">        city: string</span><br><span class="line">        country: string</span><br><span class="line">    &#125;,</span><br><span class="line">    onlineUrl?: string</span><br><span class="line">    sessions: ISession[]</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> interface ISession &#123;</span><br><span class="line">    id: number</span><br><span class="line">    name: string</span><br><span class="line">    presenter: string</span><br><span class="line">    duration: number</span><br><span class="line">    level: string</span><br><span class="line">    abstract: string</span><br><span class="line">    voters: string[]</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>2) export in shared index.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> * <span class="keyword">from</span> <span class="string">'./event.service'</span></span><br><span class="line">+ <span class="keyword">export</span> * <span class="keyword">from</span> <span class="string">'./event.model'</span></span><br></pre></td></tr></table></figure>
<p>3) event.service.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line">+ <span class="keyword">import</span> &#123; Subject, Observable &#125; <span class="keyword">from</span> <span class="string">'rxjs/RX'</span></span><br><span class="line">+ <span class="keyword">import</span> &#123; IEvent &#125; <span class="keyword">from</span> <span class="string">'./event.model'</span></span><br><span class="line"></span><br><span class="line">@Injectable()</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">EventService</span> </span>&#123;</span><br><span class="line">+    getEvents(): Observable&lt;IEvent[]&gt; &#123;</span><br><span class="line"></span><br><span class="line">        <span class="comment">//simulate async loading data operation, return subject. Need to change events-list.component.ts</span></span><br><span class="line">+        <span class="keyword">let</span> subject = <span class="keyword">new</span> Subject&lt;IEvent[]&gt;()</span><br><span class="line">        setTimeout(<span class="function"><span class="params">()</span> =&gt;</span> &#123;</span><br><span class="line">            subject.next(EVENTS);</span><br><span class="line">            subject.complete();</span><br><span class="line">        &#125;, <span class="number">100</span>)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> subject;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">+    getEvent(id: number): IEvent &#123;</span><br><span class="line">        <span class="keyword">return</span> EVENTS.find(<span class="function"><span class="params">e</span> =&gt;</span> e.id === id)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">+ <span class="keyword">const</span> EVENTS: IEvent[] = ...</span><br></pre></td></tr></table></figure>
<p>4) update <code>event:any</code> to <code>event:IEvent</code> in event-detail.component, event-list.component, event-thumbnail.component</p>
<h3 id="Creating-Your-First-Template-based-Form"><a href="#Creating-Your-First-Template-based-Form" class="headerlink" title="Creating Your First Template-based Form"></a>Creating Your First Template-based Form</h3><p>1) user/login.component.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;Component&#125; <span class="keyword">from</span> <span class="string">'@angular/core'</span></span><br><span class="line"><span class="keyword">import</span> &#123;AuthService&#125; <span class="keyword">from</span> <span class="string">'./auth.service'</span></span><br><span class="line"></span><br><span class="line">@Component(&#123;</span><br><span class="line">    templateUrl: <span class="string">'app/user/login.component.html'</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">LoginComponent</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">constructor</span>(private authService: AuthService) &#123; &#125;</span><br><span class="line"></span><br><span class="line">    login(formValues) &#123;  <span class="comment">////will be object of userName and password</span></span><br><span class="line">        <span class="keyword">this</span>.authService.loginUser(formValues.userName, formValues.password)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>2) login.component.html</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">h1</span>&gt;</span>Login<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">hr</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"col-md-4"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">form</span> #<span class="attr">loginForm</span>=<span class="string">"ngForm"</span> (<span class="attr">ngSubmit</span>)=<span class="string">"login(loginForm.value)"</span> <span class="attr">autocomplete</span>=<span class="string">"off"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"userName"</span>&gt;</span>User Name:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> (<span class="attr">ngModel</span>)=<span class="string">"userName"</span> <span class="attr">name</span>=<span class="string">"userName"</span> <span class="attr">id</span>=<span class="string">"userName"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"User Name..."</span> /&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"password"</span>&gt;</span>Password:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> (<span class="attr">ngModel</span>)=<span class="string">"password"</span> <span class="attr">name</span>=<span class="string">"password"</span> <span class="attr">id</span>=<span class="string">"password"</span> <span class="attr">type</span>=<span class="string">"password"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"Password..."</span> /&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">"submit"</span> <span class="attr">class</span>=<span class="string">"btn btn-primary"</span>&gt;</span>Login<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">"button"</span> <span class="attr">class</span>=<span class="string">"btn btn-default"</span>&gt;</span>Cancel<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>3) Register component in UserModule</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; NgModule &#125; <span class="keyword">from</span> <span class="string">'@angular/core'</span></span><br><span class="line"><span class="keyword">import</span> &#123; RouterModule &#125; <span class="keyword">from</span> <span class="string">'@angular/router'</span></span><br><span class="line"><span class="keyword">import</span> &#123; CommonModule &#125; <span class="keyword">from</span> <span class="string">'@angular/common'</span></span><br><span class="line"><span class="keyword">import</span> &#123;userRoutes&#125; <span class="keyword">from</span> <span class="string">'./user.routes'</span></span><br><span class="line"><span class="keyword">import</span> &#123;ProfileComponent&#125; <span class="keyword">from</span> <span class="string">'./profile.component'</span></span><br><span class="line">+ <span class="keyword">import</span> &#123;LoginComponent&#125; <span class="keyword">from</span> <span class="string">'./login.component'</span></span><br><span class="line">+ <span class="keyword">import</span> &#123;FormsModule&#125; <span class="keyword">from</span> <span class="string">'@angular/forms'</span></span><br><span class="line"></span><br><span class="line">@NgModule(&#123;</span><br><span class="line">    imports: [</span><br><span class="line">        CommonModule,</span><br><span class="line">+        FormsModule,</span><br><span class="line">        RouterModule.forChild(userRoutes)</span><br><span class="line">    ],</span><br><span class="line">    declarations: [</span><br><span class="line">        ProfileComponent,</span><br><span class="line">+        LoginComponent</span><br><span class="line">    ],</span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">UserModule</span> </span>&#123; &#125;</span><br></pre></td></tr></table></figure>
<p>4) Add user.routes.ts path</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;ProfileComponent&#125; <span class="keyword">from</span> <span class="string">'./profile.component'</span></span><br><span class="line">+ <span class="keyword">import</span> &#123;LoginComponent&#125; <span class="keyword">from</span> <span class="string">'./login.component'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> userRoutes = [</span><br><span class="line">    &#123; <span class="attr">path</span>: <span class="string">'profile'</span>, <span class="attr">component</span>: ProfileComponent &#125;,</span><br><span class="line">+    &#123; <span class="attr">path</span>: <span class="string">'login'</span>, <span class="attr">component</span>: LoginComponent &#125;</span><br><span class="line">]</span><br></pre></td></tr></table></figure>
<p>5) create user/user.model.ts:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> interface IUser &#123;</span><br><span class="line">    id: number</span><br><span class="line">    firstName: string</span><br><span class="line">    lastName: string</span><br><span class="line">    userName: string</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>6) create user/auth.service.ts:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;Injectable&#125; <span class="keyword">from</span> <span class="string">'@angular/core'</span></span><br><span class="line"><span class="keyword">import</span> &#123;IUser&#125; <span class="keyword">from</span> <span class="string">'./user.model'</span></span><br><span class="line"></span><br><span class="line">@Injectable()</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">AuthService</span> </span>&#123;</span><br><span class="line">    currentUser: IUser</span><br><span class="line"></span><br><span class="line">    loginUser(userName: string, <span class="attr">password</span>: string) &#123;</span><br><span class="line">        <span class="keyword">this</span>.currentUser = &#123;</span><br><span class="line">            id: <span class="number">1</span>,</span><br><span class="line">            userName: userName,</span><br><span class="line">            firstName: <span class="string">'guanghui'</span>,</span><br><span class="line">            lastName: <span class="string">'wang'</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    isAuthenticated() &#123;</span><br><span class="line">        <span class="keyword">return</span> !!<span class="keyword">this</span>.currentUser;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>7) register service in app.module.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">...</span><br><span class="line">+ <span class="keyword">import</span> &#123;AuthService&#125; <span class="keyword">from</span> <span class="string">'./user/auth.service'</span></span><br><span class="line"></span><br><span class="line">@NgModule(&#123;</span><br><span class="line">    ...</span><br><span class="line">    providers: [</span><br><span class="line">        ...</span><br><span class="line">+        AuthService</span><br><span class="line">    ],</span><br><span class="line">    bootstrap: [AppComponent]</span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">AppModule</span> </span>&#123; &#125;</span><br></pre></td></tr></table></figure>
<p>8) inject AuthService in nav.component.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;Component&#125; <span class="keyword">from</span> <span class="string">'@angular/core'</span></span><br><span class="line">+ <span class="keyword">import</span> &#123;AuthService&#125; <span class="keyword">from</span> <span class="string">'../user/auth.service'</span></span><br><span class="line"></span><br><span class="line">@Component(&#123;</span><br><span class="line">    selector: <span class="string">'nav-bar'</span>,</span><br><span class="line">    templateUrl: <span class="string">'app/nav/nav.component.html'</span>,</span><br><span class="line">    styles: [<span class="string">`</span></span><br><span class="line"><span class="string">        .nav.navbar-nav &#123;font-size:15px;&#125;</span></span><br><span class="line"><span class="string">        #searchForm &#123;margin-right:100px;&#125;</span></span><br><span class="line"><span class="string">        @media(max-width:1200px) &#123;#searchForm &#123;display:none;&#125;&#125;</span></span><br><span class="line"><span class="string">        li&gt;a.active&#123;color:#f97924;&#125;</span></span><br><span class="line"><span class="string">    `</span>]</span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">NavBarComponent</span> </span>&#123;</span><br><span class="line">+    <span class="keyword">constructor</span>(private authService: AuthService) &#123; &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>9) modify nav.component.html</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">li</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">a</span> *<span class="attr">ngIf</span>=<span class="string">"!authService.isAuthenticated()"</span> [<span class="attr">routerLink</span>]=<span class="string">"['user/login']"</span>&gt;</span>Login<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">a</span> *<span class="attr">ngIf</span>=<span class="string">"authService.isAuthenticated()"</span> [<span class="attr">routerLink</span>]=<span class="string">"['user/profile']"</span>&gt;</span>Welcome &#123;&#123;authService.currentUser.userName&#125;&#125;<span class="tag">&lt;/<span class="name">a</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">li</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>Now when you type username, password and then click login, the rightmost area in navbar’s “login” will become the userName.</p>
<p>We will finish up the other features below, like when we click login, or cancel, navigate to all events page</p>
<p>So login.component.ts:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;Component&#125; <span class="keyword">from</span> <span class="string">'@angular/core'</span></span><br><span class="line"><span class="keyword">import</span> &#123;AuthService&#125; <span class="keyword">from</span> <span class="string">'./auth.service'</span></span><br><span class="line"></span><br><span class="line">+ <span class="keyword">import</span> &#123;Router&#125; <span class="keyword">from</span> <span class="string">'@angular/router'</span></span><br><span class="line"></span><br><span class="line">@Component(&#123;</span><br><span class="line">    templateUrl: <span class="string">'app/user/login.component.html'</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">LoginComponent</span> </span>&#123;</span><br><span class="line"></span><br><span class="line">+    <span class="keyword">constructor</span>(private authService: AuthService, private router:Router) &#123; &#125;</span><br><span class="line"></span><br><span class="line">    login(formValues) &#123;</span><br><span class="line">        <span class="keyword">this</span>.authService.loginUser(formValues.userName, formValues.password)</span><br><span class="line"></span><br><span class="line">+        <span class="keyword">this</span>.router.navigate([<span class="string">'events'</span>])</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">+    cancel()&#123;</span><br><span class="line">+        <span class="keyword">this</span>.router.navigate([<span class="string">'events'</span>])</span><br><span class="line">+    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>add cancel click in login.component.html</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">"button"</span> (<span class="attr">click</span>)=<span class="string">"cancel()"</span> <span class="attr">class</span>=<span class="string">"btn btn-default"</span>&gt;</span>Cancel<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="Validating-Template-based-Forms-LoginForm"><a href="#Validating-Template-based-Forms-LoginForm" class="headerlink" title="Validating Template-based Forms (LoginForm)"></a>Validating Template-based Forms (LoginForm)</h3><p>login.component.html</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">h1</span>&gt;</span>Login<span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">hr</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"col-md-4"</span>&gt;</span></span><br><span class="line">+    <span class="tag">&lt;<span class="name">form</span> #<span class="attr">loginForm</span>=<span class="string">"ngForm"</span> (<span class="attr">ngSubmit</span>)=<span class="string">"login(loginForm.value)"</span> <span class="attr">autocomplete</span>=<span class="string">"off"</span> <span class="attr">novalidate</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"userName"</span>&gt;</span>User Name:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">+            <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"loginForm.controls.userName?.invalid &amp;&amp; (loginForm.controls.userName?.touched || mouseoverLogin)"</span>&gt;</span>Required<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">+            <span class="tag">&lt;<span class="name">input</span> <span class="attr">required</span> (<span class="attr">ngModel</span>)=<span class="string">"userName"</span> <span class="attr">name</span>=<span class="string">"userName"</span> <span class="attr">id</span>=<span class="string">"userName"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"User Name..."</span> /&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"password"</span>&gt;</span>Password:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">+            <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"loginForm.controls.password?.invalid &amp;&amp; (loginForm.controls.password?.touched || mouseoverLogin)"</span>&gt;</span>Required<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">+            <span class="tag">&lt;<span class="name">input</span> <span class="attr">required</span> (<span class="attr">ngModel</span>)=<span class="string">"password"</span> <span class="attr">name</span>=<span class="string">"password"</span> <span class="attr">id</span>=<span class="string">"password"</span> <span class="attr">type</span>=<span class="string">"password"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"Password..."</span> /&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">+        <span class="tag">&lt;<span class="name">span</span> (<span class="attr">mouseenter</span>)=<span class="string">"mouseoverLogin=true"</span> (<span class="attr">mouseleave</span>)=<span class="string">"mouseoverLogin=false"</span>&gt;</span></span><br><span class="line">+            <span class="tag">&lt;<span class="name">button</span> [<span class="attr">disabled</span>]=<span class="string">"loginForm.invalid"</span> <span class="attr">type</span>=<span class="string">"submit"</span> <span class="attr">class</span>=<span class="string">"btn btn-primary"</span>&gt;</span>Login<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">+        <span class="tag">&lt;/<span class="name">span</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">"button"</span> (<span class="attr">click</span>)=<span class="string">"cancel()"</span> <span class="attr">class</span>=<span class="string">"btn btn-default"</span>&gt;</span>Cancel<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">&lt;!-- hover on the login button, display the reason if user is not allowed login --&gt;</span></span><br><span class="line"><span class="comment">&lt;!-- disabled button cannot fire event! So have to wrap span around button --&gt;</span></span><br></pre></td></tr></table></figure>
<p>login.component.ts add styles:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">@Component(&#123;</span><br><span class="line">    templateUrl: <span class="string">'app/user/login.component.html'</span>,</span><br><span class="line">    styles:[</span><br><span class="line">        <span class="string">`em &#123;float:right;color:#e05c65;padding-left:10px;&#125;`</span></span><br><span class="line">    ]</span><br><span class="line">&#125;)</span><br></pre></td></tr></table></figure>
<h3 id="Creating-Your-First-Reactive-Form-Profile-Form"><a href="#Creating-Your-First-Reactive-Form-Profile-Form" class="headerlink" title="Creating Your First Reactive Form (Profile Form)"></a>Creating Your First Reactive Form (Profile Form)</h3><p>1) create profile.component.html and update profile.component.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; Component, OnInit &#125; <span class="keyword">from</span> <span class="string">'@angular/core'</span></span><br><span class="line"><span class="keyword">import</span> &#123; FormControl, FormGroup &#125; <span class="keyword">from</span> <span class="string">'@angular/forms'</span></span><br><span class="line"><span class="keyword">import</span> &#123; AuthService &#125; <span class="keyword">from</span> <span class="string">'./auth.service'</span></span><br><span class="line"><span class="keyword">import</span> &#123; Router &#125; <span class="keyword">from</span> <span class="string">'@angular/router'</span></span><br><span class="line"></span><br><span class="line">@Component(&#123;</span><br><span class="line">    templateUrl: <span class="string">'app/user/profile.component.html'</span></span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">ProfileComponent</span> <span class="title">implements</span> <span class="title">OnInit</span> </span>&#123;</span><br><span class="line">    <span class="keyword">constructor</span>(private authService: AuthService, private router: Router) &#123; &#125;</span><br><span class="line"></span><br><span class="line">    profileForm: FormGroup</span><br><span class="line"></span><br><span class="line">    ngOnInit() &#123;</span><br><span class="line">        <span class="keyword">let</span> firstName = <span class="keyword">new</span> FormControl(<span class="keyword">this</span>.authService.currentUser.firstName)</span><br><span class="line">        <span class="keyword">let</span> lastName = <span class="keyword">new</span> FormControl(<span class="keyword">this</span>.authService.currentUser.lastName)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">this</span>.profileForm = <span class="keyword">new</span> FormGroup(&#123;</span><br><span class="line">            firstName: firstName,</span><br><span class="line">            lastName: lastName</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    cancel() &#123;</span><br><span class="line">        <span class="keyword">this</span>.router.navigate([<span class="string">'events'</span>])</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    saveProfile(formValues) &#123;</span><br><span class="line">        <span class="keyword">this</span>.authService.updateCurrentUser(formValues.firstName, formValues.lastName)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">this</span>.router.navigate([<span class="string">'events'</span>])</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h1</span>&gt;</span>Edit Your Profile <span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">hr</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"col-md-4"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">form</span> [<span class="attr">formGroup</span>]=<span class="string">"profileForm"</span> (<span class="attr">ngSubmit</span>)=<span class="string">"saveProfile(profileForm.value)"</span> <span class="attr">autocomplete</span>=<span class="string">"off"</span> <span class="attr">novalidate</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"firstName"</span>&gt;</span>First Name:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">input</span> <span class="attr">formControlName</span>=<span class="string">"firstName"</span> <span class="attr">id</span>=<span class="string">"firstName"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"First Name..."</span> /&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"lastName"</span>&gt;</span>Last Name:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">input</span> <span class="attr">formControlName</span>=<span class="string">"lastName"</span> <span class="attr">id</span>=<span class="string">"lastName"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"Last Name..."</span> /&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">            <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">"submit"</span> <span class="attr">class</span>=<span class="string">"btn btn-primary"</span>&gt;</span>Save<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">button</span> (<span class="attr">click</span>)=<span class="string">"cancel()"</span> <span class="attr">type</span>=<span class="string">"button"</span> <span class="attr">class</span>=<span class="string">"btn btn-default"</span>&gt;</span>Cancel<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>2) import ReactiveFormsModule into user.module.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">...</span><br><span class="line">+ <span class="keyword">import</span> &#123;FormsModule,ReactiveFormsModule&#125; <span class="keyword">from</span> <span class="string">'@angular/forms'</span></span><br><span class="line"></span><br><span class="line">@NgModule(&#123;</span><br><span class="line">    imports: [</span><br><span class="line">        CommonModule,</span><br><span class="line">        FormsModule,</span><br><span class="line">+        ReactiveFormsModule,</span><br><span class="line">        RouterModule.forChild(userRoutes)</span><br><span class="line">    ],</span><br><span class="line">    ...</span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">UserModule</span> </span>&#123; &#125;</span><br></pre></td></tr></table></figure>
<p>3) add updateCurrentUser method in authService</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">AuthService</span> </span>&#123;</span><br><span class="line">    ...</span><br><span class="line"></span><br><span class="line">    updateCurrentUser(firstName: string, <span class="attr">lastName</span>: string) &#123;</span><br><span class="line">        <span class="keyword">this</span>.currentUser.firstName = firstName;</span><br><span class="line">        <span class="keyword">this</span>.currentUser.lastName = lastName;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<h3 id="Validating-Reactive-Forms"><a href="#Validating-Reactive-Forms" class="headerlink" title="Validating Reactive Forms"></a>Validating Reactive Forms</h3><p>1) add required Validators, error style, validateFirstName, validateLastName functions in profile.component.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; Component, OnInit &#125; <span class="keyword">from</span> <span class="string">'@angular/core'</span></span><br><span class="line">+ <span class="keyword">import</span> &#123; FormControl, FormGroup, Validators &#125; <span class="keyword">from</span> <span class="string">'@angular/forms'</span></span><br><span class="line"><span class="keyword">import</span> &#123; AuthService &#125; <span class="keyword">from</span> <span class="string">'./auth.service'</span></span><br><span class="line"><span class="keyword">import</span> &#123; Router &#125; <span class="keyword">from</span> <span class="string">'@angular/router'</span></span><br><span class="line"></span><br><span class="line">@Component(&#123;</span><br><span class="line">    templateUrl: <span class="string">'app/user/profile.component.html'</span>,</span><br><span class="line">+    styles: [</span><br><span class="line">        <span class="string">`</span></span><br><span class="line"><span class="string">        em &#123;float:right;color:#e05c65;padding-left:10px;&#125;</span></span><br><span class="line"><span class="string">        .error input&#123;background-color:#e3c3c5;&#125;</span></span><br><span class="line"><span class="string">        .error ::-webkit-input-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        .error ::-moz-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        .error :-ms-input-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        `</span></span><br><span class="line">    ]</span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">ProfileComponent</span> <span class="title">implements</span> <span class="title">OnInit</span> </span>&#123;</span><br><span class="line">    <span class="keyword">constructor</span>(private authService: AuthService, private router: Router) &#123; &#125;</span><br><span class="line"></span><br><span class="line">    profileForm: FormGroup</span><br><span class="line">+   private firstName: FormControl</span><br><span class="line">+   private lastName: FormControl</span><br><span class="line"></span><br><span class="line">    ngOnInit() &#123;</span><br><span class="line">+        <span class="keyword">this</span>.firstName = <span class="keyword">new</span> FormControl(<span class="keyword">this</span>.authService.currentUser.firstName, Validators.required)</span><br><span class="line">+        <span class="keyword">this</span>.lastName = <span class="keyword">new</span> FormControl(<span class="keyword">this</span>.authService.currentUser.lastName, Validators.required)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">this</span>.profileForm = <span class="keyword">new</span> FormGroup(&#123;</span><br><span class="line">+            firstName: <span class="keyword">this</span>.firstName,</span><br><span class="line">+            lastName: <span class="keyword">this</span>.lastName</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    cancel() &#123;</span><br><span class="line">        <span class="keyword">this</span>.router.navigate([<span class="string">'events'</span>])</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    saveProfile(formValues) &#123;</span><br><span class="line">+        <span class="keyword">if</span> (<span class="keyword">this</span>.profileForm.valid) &#123;</span><br><span class="line">            <span class="keyword">this</span>.authService.updateCurrentUser(formValues.firstName, formValues.lastName)</span><br><span class="line">            <span class="keyword">this</span>.router.navigate([<span class="string">'events'</span>])</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">+    validateFirstName() &#123;</span><br><span class="line">+        <span class="keyword">return</span> <span class="keyword">this</span>.firstName.valid || <span class="keyword">this</span>.firstName.untouched</span><br><span class="line">+    &#125;</span><br><span class="line"></span><br><span class="line">+    validateLastName() &#123;</span><br><span class="line">+        <span class="keyword">return</span> <span class="keyword">this</span>.lastName.valid || <span class="keyword">this</span>.lastName.untouched</span><br><span class="line">+    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>2) update profile template:</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h1</span>&gt;</span>Edit Your Profile <span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">hr</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"col-md-4"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">form</span> [<span class="attr">formGroup</span>]=<span class="string">"profileForm"</span> (<span class="attr">ngSubmit</span>)=<span class="string">"saveProfile(profileForm.value)"</span> <span class="attr">autocomplete</span>=<span class="string">"off"</span> <span class="attr">novalidate</span>&gt;</span></span><br><span class="line">+            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span> [<span class="attr">ngClass</span>]=<span class="string">"&#123;'error': !validateFirstName()&#125;"</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"firstName"</span>&gt;</span>First Name:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">+                <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"!validateFirstName()"</span>&gt;</span>Required<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">input</span> <span class="attr">formControlName</span>=<span class="string">"firstName"</span> <span class="attr">id</span>=<span class="string">"firstName"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"First Name..."</span> /&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">+            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span> [<span class="attr">ngClass</span>]=<span class="string">"&#123;'error': !validateLastName()&#125;"</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"lastName"</span>&gt;</span>Last Name:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">+                <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"!validateLastName()"</span>&gt;</span>Required<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">input</span> <span class="attr">formControlName</span>=<span class="string">"lastName"</span> <span class="attr">id</span>=<span class="string">"lastName"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"Last Name..."</span> /&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"></span><br><span class="line">            <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">"submit"</span> <span class="attr">class</span>=<span class="string">"btn btn-primary"</span>&gt;</span>Save<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">button</span> (<span class="attr">click</span>)=<span class="string">"cancel()"</span> <span class="attr">type</span>=<span class="string">"button"</span> <span class="attr">class</span>=<span class="string">"btn btn-default"</span>&gt;</span>Cancel<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="Using-Multiple-Validators-in-Reactive-Forms"><a href="#Using-Multiple-Validators-in-Reactive-Forms" class="headerlink" title="Using Multiple Validators in Reactive Forms"></a>Using Multiple Validators in Reactive Forms</h3><p>Let’s say we want firstName starts with a letter, so we add Validators.pattern</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; FormControl, FormGroup, Validators &#125; <span class="keyword">from</span> <span class="string">'@angular/forms'</span></span><br><span class="line"></span><br><span class="line">@Component(&#123;</span><br><span class="line">    templateUrl: <span class="string">'app/user/profile.component.html'</span>,</span><br><span class="line">    styles: [</span><br><span class="line">        <span class="string">`</span></span><br><span class="line"><span class="string">        em &#123;float:right;color:#e05c65;padding-left:10px;&#125;</span></span><br><span class="line"><span class="string">        .error input&#123;background-color:#e3c3c5;&#125;</span></span><br><span class="line"><span class="string">        .error ::-webkit-input-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        .error ::-moz-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        .error :-ms-input-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        `</span></span><br><span class="line">    ]</span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">ProfileComponent</span> <span class="title">implements</span> <span class="title">OnInit</span> </span>&#123;</span><br><span class="line">    <span class="keyword">constructor</span>(private authService: AuthService, private router: Router) &#123; &#125;</span><br><span class="line"></span><br><span class="line">    profileForm: FormGroup</span><br><span class="line">    firstName: FormControl</span><br><span class="line">    lastName: FormControl</span><br><span class="line"></span><br><span class="line">    ngOnInit() &#123;</span><br><span class="line">+        <span class="keyword">this</span>.firstName = <span class="keyword">new</span> FormControl(<span class="keyword">this</span>.authService.currentUser.firstName, [Validators.required, Validators.pattern(<span class="string">'[a-zA-Z].*'</span>)])</span><br><span class="line">        <span class="keyword">this</span>.lastName = <span class="keyword">new</span> FormControl(<span class="keyword">this</span>.authService.currentUser.lastName, Validators.required)</span><br><span class="line"></span><br><span class="line">        <span class="keyword">this</span>.profileForm = <span class="keyword">new</span> FormGroup(&#123;</span><br><span class="line">            firstName: <span class="keyword">this</span>.firstName,</span><br><span class="line">            lastName: <span class="keyword">this</span>.lastName</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line">    ...</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>profile template:</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h1</span>&gt;</span>Edit Your Profile <span class="tag">&lt;/<span class="name">h1</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">hr</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"col-md-4"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">form</span> [<span class="attr">formGroup</span>]=<span class="string">"profileForm"</span> (<span class="attr">ngSubmit</span>)=<span class="string">"saveProfile(profileForm.value)"</span> <span class="attr">autocomplete</span>=<span class="string">"off"</span> <span class="attr">novalidate</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span> [<span class="attr">ngClass</span>]=<span class="string">"&#123;'error': !validateFirstName()&#125;"</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"firstName"</span>&gt;</span>First Name:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">+                <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"!validateFirstName() &amp;&amp; profileForm.controls.firstName.errors.required"</span>&gt;</span>Required<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">+                <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"!validateFirstName() &amp;&amp; profileForm.controls.firstName.errors.pattern"</span>&gt;</span>firstName starts with a letter<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">input</span> <span class="attr">formControlName</span>=<span class="string">"firstName"</span> <span class="attr">id</span>=<span class="string">"firstName"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"First Name..."</span> /&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">            ...</span><br><span class="line">        <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>
<h3 id="Diving-Deeper-into-Template-based-Forms-Create-New-Event"><a href="#Diving-Deeper-into-Template-based-Forms-Create-New-Event" class="headerlink" title="Diving Deeper into Template-based Forms (Create New Event)"></a>Diving Deeper into Template-based Forms (Create New Event)</h3><p>1) add create-event.component.html</p>
<p>2) create-event.component.ts: Add styles, saveEvent</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//click cancel will use router to navigate to /events (load all events)</span></span><br><span class="line"><span class="keyword">import</span> &#123;Component&#125; <span class="keyword">from</span> <span class="string">'@angular/core'</span></span><br><span class="line"><span class="keyword">import</span> &#123;Router&#125; <span class="keyword">from</span> <span class="string">'@angular/router'</span></span><br><span class="line"><span class="keyword">import</span> &#123;EventService&#125; <span class="keyword">from</span> <span class="string">'./shared/event.service'</span></span><br><span class="line"></span><br><span class="line">@Component(&#123;</span><br><span class="line">    templateUrl: <span class="string">'app/events/create-event.component.html'</span>,</span><br><span class="line">    styles: [</span><br><span class="line">        <span class="string">`</span></span><br><span class="line"><span class="string">        em &#123;float:right;color:#e05c65;padding-left:10px;&#125;</span></span><br><span class="line"><span class="string">        .error input&#123;background-color:#e3c3c5;&#125;</span></span><br><span class="line"><span class="string">        .error ::-webkit-input-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        .error ::-moz-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        .error :-ms-input-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        `</span></span><br><span class="line">    ]</span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">CreateEventComponent</span> </span>&#123;</span><br><span class="line">    isDirty: boolean = <span class="literal">true</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">constructor</span>(private router: Router, private eventService: EventService) &#123; &#125;</span><br><span class="line"></span><br><span class="line">    cancel() &#123;</span><br><span class="line">        <span class="keyword">this</span>.router.navigate([<span class="string">'/events'</span>])</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    saveEvent(formValues) &#123;</span><br><span class="line">        <span class="keyword">this</span>.eventService.saveEvent(formValues)</span><br><span class="line">        <span class="keyword">this</span>.isDirty = <span class="literal">false</span></span><br><span class="line">        <span class="keyword">this</span>.router.navigate([<span class="string">'/events'</span>])</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>we can now add a temporary method in event.service.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">saveEvent(event)&#123;</span><br><span class="line">    event.id = <span class="number">999</span>;</span><br><span class="line">    event.sessions = [];</span><br><span class="line">    EVENTS.push(event);</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>3) import FormsModule, ReactiveFormsModule in app.module.ts</p>
<p>4) now when we submit the form, formValues is a object that has city, address, country, name, etc. They are at same level. Our model structure actually has location property which includes address, city, country. So we can use ngModelGroup to wrap up these 3 fields.</p>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">+ <span class="tag">&lt;<span class="name">div</span> <span class="attr">ngModelGroup</span>=<span class="string">"location"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"address"</span>&gt;</span>Event Location:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">input</span> (<span class="attr">ngModel</span>)=<span class="string">"address"</span> <span class="attr">name</span>=<span class="string">"address"</span> <span class="attr">id</span>=<span class="string">"address"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"Address of event..."</span> /&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"row"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"col-md-6"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> (<span class="attr">ngModel</span>)=<span class="string">"city"</span> <span class="attr">name</span>=<span class="string">"city"</span> <span class="attr">id</span>=<span class="string">"city"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"City..."</span> /&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"col-md-6"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> (<span class="attr">ngModel</span>)=<span class="string">"country"</span> <span class="attr">name</span>=<span class="string">"country"</span> <span class="attr">id</span>=<span class="string">"country"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"Country..."</span> /&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">+ <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>data is like  <code>{name: &quot;fdsa&quot;, date: &quot;1010/2/2&quot;, time: &quot;8:00&quot;, price: 34432, location: {address: &quot;fds&quot;, city: &quot;fdasfdas&quot;, country: &quot;fdsa&quot;}, …}</code></p>
<h3 id="Diving-Deeper-into-Reactive-Forms-Event-detail-shows-session"><a href="#Diving-Deeper-into-Reactive-Forms-Event-detail-shows-session" class="headerlink" title="Diving Deeper into Reactive Forms (Event-detail shows session)"></a>Diving Deeper into Reactive Forms (Event-detail shows session)</h3><p>1) create /events/event-detail/create-session.component.ts, its template. Don’t forget to export in index.ts and register in app.module.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; Component, OnInit &#125; <span class="keyword">from</span> <span class="string">'@angular/core'</span></span><br><span class="line"><span class="keyword">import</span> &#123; FormControl, FormGroup, Validators &#125; <span class="keyword">from</span> <span class="string">'@angular/forms'</span></span><br><span class="line"><span class="keyword">import</span> &#123; ISession &#125; <span class="keyword">from</span> <span class="string">'../shared/index'</span></span><br><span class="line"></span><br><span class="line">@Component(&#123;</span><br><span class="line">    templateUrl: <span class="string">'app/events/event-detail/create-session.component.html'</span>,</span><br><span class="line">    styles: [</span><br><span class="line">        <span class="string">`</span></span><br><span class="line"><span class="string">        em &#123;float:right;color:#e05c65;padding-left:10px;&#125;</span></span><br><span class="line"><span class="string">        .error input, .error select, .error textarea &#123;background-color:#e3c3c5;&#125;</span></span><br><span class="line"><span class="string">        .error ::-webkit-input-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        .error ::-moz-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        .error :-ms-input-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        `</span></span><br><span class="line">    ]</span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">CreateSessionComponent</span> <span class="title">implements</span> <span class="title">OnInit</span> </span>&#123;</span><br><span class="line">    newSessionForm: FormGroup</span><br><span class="line">    name: FormControl</span><br><span class="line">    presenter: FormControl</span><br><span class="line">    duration: FormControl</span><br><span class="line">    level: FormControl</span><br><span class="line">    abstract: FormControl</span><br><span class="line"></span><br><span class="line">    ngOnInit() &#123;</span><br><span class="line">        <span class="keyword">this</span>.name = <span class="keyword">new</span> FormControl(<span class="string">''</span>, Validators.required)</span><br><span class="line">        <span class="keyword">this</span>.presenter = <span class="keyword">new</span> FormControl(<span class="string">''</span>, Validators.required)</span><br><span class="line">        <span class="keyword">this</span>.duration = <span class="keyword">new</span> FormControl(<span class="string">''</span>, Validators.required)</span><br><span class="line">        <span class="keyword">this</span>.level = <span class="keyword">new</span> FormControl(<span class="string">''</span>, Validators.required)</span><br><span class="line">        <span class="keyword">this</span>.abstract = <span class="keyword">new</span> FormControl(<span class="string">''</span>, [Validators.required, Validators.maxLength(<span class="number">400</span>)])</span><br><span class="line"></span><br><span class="line">        <span class="keyword">this</span>.newSessionForm = <span class="keyword">new</span> FormGroup(&#123;</span><br><span class="line">            name: <span class="keyword">this</span>.name,</span><br><span class="line">            presenter: <span class="keyword">this</span>.presenter,</span><br><span class="line">            duration: <span class="keyword">this</span>.duration,</span><br><span class="line">            level: <span class="keyword">this</span>.level,</span><br><span class="line">            abstract: <span class="keyword">this</span>.abstract</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    saveSession(formValues) &#123;</span><br><span class="line">        <span class="comment">// console.log(formValues);</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">let</span> session: ISession = &#123;</span><br><span class="line">            id: <span class="literal">undefined</span>,</span><br><span class="line">            name: formValues.name,</span><br><span class="line">            duration: +formValues.duration,  <span class="comment">//convert</span></span><br><span class="line">            presenter: formValues.presenter,</span><br><span class="line">            level: formValues.level,</span><br><span class="line">            abstract: formValues.abstract,</span><br><span class="line">            voters: []</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">console</span>.log(session)</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"col-md-12"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">h3</span>&gt;</span>Create Session<span class="tag">&lt;/<span class="name">h3</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"col-md-6"</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;<span class="name">form</span> [<span class="attr">formGroup</span>]=<span class="string">"newSessionForm"</span> (<span class="attr">ngSubmit</span>)=<span class="string">"saveSession(newSessionForm.value)"</span> <span class="attr">autocomplete</span>=<span class="string">"off"</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span> [<span class="attr">ngClass</span>]=<span class="string">"&#123;'error': name.invalid &amp;&amp; name.dirty&#125;"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"sessionName"</span>&gt;</span>Session Name:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"name.invalid &amp;&amp; name.dirty"</span>&gt;</span>Required<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> <span class="attr">formControlName</span>=<span class="string">"name"</span> <span class="attr">id</span>=<span class="string">"sessionName"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"session name..."</span> /&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span> [<span class="attr">ngClass</span>]=<span class="string">"&#123;'error': presenter.invalid &amp;&amp; presenter.dirty&#125;"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"presenter"</span>&gt;</span>Presenter:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"presenter.invalid &amp;&amp; presenter.dirty"</span>&gt;</span>Required<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">input</span> <span class="attr">formControlName</span>=<span class="string">"presenter"</span> <span class="attr">id</span>=<span class="string">"presenter"</span> <span class="attr">type</span>=<span class="string">"text"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"presenter..."</span> /&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span> [<span class="attr">ngClass</span>]=<span class="string">"&#123;'error': duration.invalid &amp;&amp; duration.dirty&#125;"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"duration"</span>&gt;</span>Duration:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"duration.invalid &amp;&amp; duration.dirty"</span>&gt;</span>Required<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">select</span> <span class="attr">formControlName</span>=<span class="string">"duration"</span> <span class="attr">class</span>=<span class="string">"form-control"</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">""</span>&gt;</span>select duration...<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">"1"</span>&gt;</span>Half Hour<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">"2"</span>&gt;</span>1 Hour<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">"3"</span>&gt;</span>Half Day<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">"4"</span>&gt;</span>Full Day<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span> [<span class="attr">ngClass</span>]=<span class="string">"&#123;'error': level.invalid &amp;&amp; level.dirty&#125;"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"level"</span>&gt;</span>Level:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"level.invalid &amp;&amp; level.dirty"</span>&gt;</span>Required<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">select</span> <span class="attr">formControlName</span>=<span class="string">"level"</span> <span class="attr">class</span>=<span class="string">"form-control"</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">""</span>&gt;</span>select level...<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">"Beginner"</span>&gt;</span>Beginner<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">"Intermediate"</span>&gt;</span>Intermediate<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">                <span class="tag">&lt;<span class="name">option</span> <span class="attr">value</span>=<span class="string">"Advanced"</span>&gt;</span>Advanced<span class="tag">&lt;/<span class="name">option</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;/<span class="name">select</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">div</span> <span class="attr">class</span>=<span class="string">"form-group"</span> [<span class="attr">ngClass</span>]=<span class="string">"&#123;'error': abstract.invalid &amp;&amp; abstract.dirty&#125;"</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">label</span> <span class="attr">for</span>=<span class="string">"abstract"</span>&gt;</span>Abstract:<span class="tag">&lt;/<span class="name">label</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"abstract.invalid &amp;&amp; abstract.dirty &amp;&amp; abstract?.errors.required"</span>&gt;</span>Required<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">em</span> *<span class="attr">ngIf</span>=<span class="string">"abstract.invalid &amp;&amp; abstract.dirty &amp;&amp; abstract?.errors.maxlength"</span>&gt;</span>Cannot exceed 400 characters<span class="tag">&lt;/<span class="name">em</span>&gt;</span></span><br><span class="line">            <span class="tag">&lt;<span class="name">textarea</span> <span class="attr">formControlName</span>=<span class="string">"abstract"</span> <span class="attr">id</span>=<span class="string">"abstract"</span> <span class="attr">rows</span>=<span class="string">"3"</span> <span class="attr">class</span>=<span class="string">"form-control"</span> <span class="attr">placeholder</span>=<span class="string">"abstract..."</span>&gt;</span><span class="tag">&lt;/<span class="name">textarea</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">"submit"</span> [<span class="attr">disabled</span>]=<span class="string">"newSessionForm.invalid"</span> <span class="attr">class</span>=<span class="string">"btn btn-primary"</span>&gt;</span>Save<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">        <span class="tag">&lt;<span class="name">button</span> <span class="attr">type</span>=<span class="string">"button"</span> <span class="attr">class</span>=<span class="string">"btn btn-default"</span>&gt;</span>Cancel<span class="tag">&lt;/<span class="name">button</span>&gt;</span></span><br><span class="line">    <span class="tag">&lt;/<span class="name">form</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">div</span>&gt;</span></span><br></pre></td></tr></table></figure>
<p>2) register it in routes.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;CreateSessionComponent&#125; <span class="keyword">from</span> <span class="string">'./events/event-detail/create-session.component'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">const</span> appRoutes: Routes = [</span><br><span class="line">    <span class="comment">//order matters</span></span><br><span class="line">    &#123; <span class="attr">path</span>: <span class="string">'events/new'</span>, <span class="attr">component</span>: CreateEventComponent, <span class="attr">canDeactivate</span>: [<span class="string">'canDeactivateCreateEvent'</span>] &#125;, <span class="comment">//Guarding Against Route De-activation using function, canDeactivateCreateEvent is provider name which points to a function</span></span><br><span class="line">    &#123; <span class="attr">path</span>: <span class="string">'events'</span>, <span class="attr">component</span>: EventsListComponent, <span class="attr">resolve</span>: &#123; <span class="attr">events1</span>: EventListResolver &#125; &#125;, <span class="comment">//call EventListResolver before using the component, bind resolver result to a property events1, and this property will be passed to the component</span></span><br><span class="line">    &#123; <span class="attr">path</span>: <span class="string">'events/:id'</span>, <span class="attr">component</span>: EventDetailComponent, <span class="attr">canActivate</span>: [EventRouteActivator] &#125;, <span class="comment">//Guarding Against Route Activation using service</span></span><br><span class="line">+    &#123; <span class="attr">path</span>: <span class="string">'events/session/new'</span>, <span class="attr">component</span>: CreateSessionComponent &#125;,</span><br><span class="line">    &#123; <span class="attr">path</span>: <span class="string">'404'</span>, <span class="attr">component</span>: Error404Component &#125;,</span><br><span class="line">    &#123; <span class="attr">path</span>: <span class="string">''</span>, <span class="attr">redirectTo</span>: <span class="string">'/events'</span>, <span class="attr">pathMatch</span>: <span class="string">'full'</span> &#125;,  <span class="comment">//pathMatch: prefix or full</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// user prefix, localhost/user/x, will load module here: app/user/user.module and the module name is UserModule, concat '#'</span></span><br><span class="line">    &#123; <span class="attr">path</span>: <span class="string">'user'</span>, <span class="attr">loadChildren</span>: <span class="string">'app/user/user.module#UserModule'</span> &#125;</span><br><span class="line">]</span><br></pre></td></tr></table></figure>
<h3 id="Custom-Validation"><a href="#Custom-Validation" class="headerlink" title="Custom Validation"></a>Custom Validation</h3><p>create-session.component.ts</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123; Component, OnInit &#125; <span class="keyword">from</span> <span class="string">'@angular/core'</span></span><br><span class="line"><span class="keyword">import</span> &#123; FormControl, FormGroup, Validators &#125; <span class="keyword">from</span> <span class="string">'@angular/forms'</span></span><br><span class="line"><span class="keyword">import</span> &#123; ISession, restrictedWords &#125; <span class="keyword">from</span> <span class="string">'../shared/index'</span></span><br><span class="line"></span><br><span class="line">@Component(&#123;</span><br><span class="line">    templateUrl: <span class="string">'app/events/event-detail/create-session.component.html'</span>,</span><br><span class="line">    styles: [</span><br><span class="line">        <span class="string">`</span></span><br><span class="line"><span class="string">        em &#123;float:right;color:#e05c65;padding-left:10px;&#125;</span></span><br><span class="line"><span class="string">        .error input, .error select, .error textarea &#123;background-color:#e3c3c5;&#125;</span></span><br><span class="line"><span class="string">        .error ::-webkit-input-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        .error ::-moz-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        .error :-ms-input-placeholder &#123;color:#999;&#125;</span></span><br><span class="line"><span class="string">        `</span></span><br><span class="line">    ]</span><br><span class="line">&#125;)</span><br><span class="line"><span class="keyword">export</span> <span class="class"><span class="keyword">class</span> <span class="title">CreateSessionComponent</span> <span class="title">implements</span> <span class="title">OnInit</span> </span>&#123;</span><br><span class="line">    newSessionForm: FormGroup</span><br><span class="line">    name: FormControl</span><br><span class="line">    presenter: FormControl</span><br><span class="line">    duration: FormControl</span><br><span class="line">    level: FormControl</span><br><span class="line">    abstract: FormControl</span><br><span class="line"></span><br><span class="line">    ngOnInit() &#123;</span><br><span class="line">        <span class="keyword">this</span>.name = <span class="keyword">new</span> FormControl(<span class="string">''</span>, Validators.required)</span><br><span class="line">        <span class="keyword">this</span>.presenter = <span class="keyword">new</span> FormControl(<span class="string">''</span>, Validators.required)</span><br><span class="line">        <span class="keyword">this</span>.duration = <span class="keyword">new</span> FormControl(<span class="string">''</span>, Validators.required)</span><br><span class="line">        <span class="keyword">this</span>.level = <span class="keyword">new</span> FormControl(<span class="string">''</span>, Validators.required)</span><br><span class="line">        <span class="keyword">this</span>.abstract = <span class="keyword">new</span> FormControl(<span class="string">''</span>, [Validators.required, Validators.maxLength(<span class="number">400</span>), restrictedWords([<span class="string">'foo'</span>, <span class="string">'bar'</span>])])</span><br><span class="line"></span><br><span class="line">        <span class="keyword">this</span>.newSessionForm = <span class="keyword">new</span> FormGroup(&#123;</span><br><span class="line">            name: <span class="keyword">this</span>.name,</span><br><span class="line">            presenter: <span class="keyword">this</span>.presenter,</span><br><span class="line">            duration: <span class="keyword">this</span>.duration,</span><br><span class="line">            level: <span class="keyword">this</span>.level,</span><br><span class="line">            abstract: <span class="keyword">this</span>.abstract</span><br><span class="line">        &#125;)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    saveSession(formValues) &#123;</span><br><span class="line">        <span class="comment">// console.log(formValues);</span></span><br><span class="line"></span><br><span class="line">        <span class="keyword">let</span> session: ISession = &#123;</span><br><span class="line">            id: <span class="literal">undefined</span>,</span><br><span class="line">            name: formValues.name,</span><br><span class="line">            duration: +formValues.duration,  <span class="comment">//convert</span></span><br><span class="line">            presenter: formValues.presenter,</span><br><span class="line">            level: formValues.level,</span><br><span class="line">            abstract: formValues.abstract,</span><br><span class="line">            voters: []</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="built_in">console</span>.log(session)</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">//custom validation</span></span><br><span class="line">    <span class="comment">// private restrictedWords(control: FormControl): &#123; [key: string]: any &#125; &#123;</span></span><br><span class="line">    <span class="comment">//     return control.value.includes('foo')</span></span><br><span class="line">    <span class="comment">//         ? &#123; 'restrictedWords': 'foo' &#125;</span></span><br><span class="line">    <span class="comment">//         : null</span></span><br><span class="line">    <span class="comment">// &#125;</span></span><br><span class="line"></span><br><span class="line">    <span class="comment">// this will be put into shared folder</span></span><br><span class="line">    <span class="comment">// private restrictedWords(words) &#123;</span></span><br><span class="line">    <span class="comment">//     return (control: FormControl): &#123; [key: string]: any &#125; =&gt; &#123;</span></span><br><span class="line">    <span class="comment">//</span></span><br><span class="line">    <span class="comment">//         if (!words) return null;</span></span><br><span class="line">    <span class="comment">//</span></span><br><span class="line">    <span class="comment">//         var invalidWords = words.map(w =&gt; control.value.includes(w) ? w : null)</span></span><br><span class="line">    <span class="comment">//             .filter(w =&gt; w != null);</span></span><br><span class="line">    <span class="comment">//</span></span><br><span class="line">    <span class="comment">//         return invalidWords &amp;&amp; invalidWords.length &gt; 0</span></span><br><span class="line">    <span class="comment">//             ? &#123; 'restrictedWords': invalidWords.join(', ') &#125;</span></span><br><span class="line">    <span class="comment">//             : null</span></span><br><span class="line">    <span class="comment">//     &#125;</span></span><br><span class="line">    <span class="comment">// &#125;</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>shared/restricted-words.validator.ts, and don’t forget export in index.ts barrel</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> &#123;FormControl&#125; <span class="keyword">from</span> <span class="string">'@angular/forms'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="function"><span class="keyword">function</span> <span class="title">restrictedWords</span>(<span class="params">words</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> (control: FormControl): &#123; [key: string]: any &#125; =&gt; &#123;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">if</span> (!words) <span class="keyword">return</span> <span class="literal">null</span>;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">var</span> invalidWords = words.map(<span class="function"><span class="params">w</span> =&gt;</span> control.value.includes(w) ? w : <span class="literal">null</span>)</span><br><span class="line">            .filter(<span class="function"><span class="params">w</span> =&gt;</span> w != <span class="literal">null</span>);</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> invalidWords &amp;&amp; invalidWords.length &gt; <span class="number">0</span></span><br><span class="line">            ? &#123; <span class="string">'restrictedWords'</span>: invalidWords.join(<span class="string">', '</span>) &#125;</span><br><span class="line">            : <span class="literal">null</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

                <!-- <hr> -->
                

                <ul class="pager">
                    
                    <li class="previous">
                        <a href="/2017/04/23/angular2-chapter05/" data-toggle="tooltip" data-placement="top"
                           title="angular2-chapter05 -- Routing and Navigation">&larr; Previous Post</a>
                    </li>
                    
                    
                    <li class="next">
                        <a href="/2017/04/29/angular2-chapter07/" data-toggle="tooltip" data-placement="top"
                           title="angular2-chapter07 -- Components Communicating">Next Post &rarr;</a>
                    </li>
                    
                </ul>

                <!-- social-share start -->
                <div class="social-share" style="padding-top:20px;text-align:center;"></div>
                <!--  css & js -->
                <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/social-share.js/1.0.16/css/share.min.css
                ">
                <script src="https://cdnjs.cloudflare.com/ajax/libs/social-share.js/1.0.16/js/social-share.min.js"></script>
                <!-- social-share end -->


                

                
                <!-- disqus 评论框 start -->
                <div class="comment">
                    <div id="disqus_thread" class="disqus-thread"></div>
                </div>
                <!-- disqus 评论框 end -->
                

            </div>

            <div class="hidden-xs col-sm-3 toc-col">
                <div class="toc-wrap">
                    <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#Collecting-Data-with-Forms-and-Validation"><span class="toc-text">Collecting Data with Forms and Validation</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#Using-Models-for-Type-Safety"><span class="toc-text">Using Models for Type Safety</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Creating-Your-First-Template-based-Form"><span class="toc-text">Creating Your First Template-based Form</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Validating-Template-based-Forms-LoginForm"><span class="toc-text">Validating Template-based Forms (LoginForm)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Creating-Your-First-Reactive-Form-Profile-Form"><span class="toc-text">Creating Your First Reactive Form (Profile Form)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Validating-Reactive-Forms"><span class="toc-text">Validating Reactive Forms</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Using-Multiple-Validators-in-Reactive-Forms"><span class="toc-text">Using Multiple Validators in Reactive Forms</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Diving-Deeper-into-Template-based-Forms-Create-New-Event"><span class="toc-text">Diving Deeper into Template-based Forms (Create New Event)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Diving-Deeper-into-Reactive-Forms-Event-detail-shows-session"><span class="toc-text">Diving Deeper into Reactive Forms (Event-detail shows session)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#Custom-Validation"><span class="toc-text">Custom Validation</span></a></li></ol></li></ol></li></ol>
                </div>
            </div>
        </div>

        <div class="row">
            <!-- Sidebar Container -->

            <div class="
                col-lg-8 col-lg-offset-2
                col-md-10 col-md-offset-1
                sidebar-container">

                <!-- Featured Tags -->
                
                <section>
                    <!-- no hr -->
                    <h5 class="text-center">
                        <a href="/tags/">FEATURED TAGS</a>
                    </h5>
                    <div class="tags">
                        
                        <a class="tag" href="/tags/#Angular2"
                           title="Angular2">Angular2</a>
                        
                    </div>
                </section>
                

                <!-- Friends Blog -->
                
            </div>
        </div>

    </div>
</article>

<div id="music">
    <audio id="bell" src="/music/Faded.mp3" preload="auto" loop autoplay></audio>
</div>
<!-- <embed style="position:fixed;right:0;bottom:0;"; src="http://www.xiami.com/widget/274513503_1776204257/singlePlayer.swf" type="application/x-shockwave-flash" width="257" height="33" wmode="transparent"></embed> -->
<!-- <embed style="position:fixed;right:0;bottom:-44px;"; src="http://www.xiami.com/widget/274513503_1775988866,1774426379,1770760772,1772121439,3567313,_235_246_FF8719_494949/multiPlayer.swf" allowscriptaccess="always" quality="high" wmode="opaque" menu="false" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="235" height="246" title="Adobe Flash Player"> -->
<!-- music control -->
<script src="/js/music.js"></script>

<div class="gotoTop"></div>
<script src="/js/gotoTop.js"></script>



<!-- disqus 公共JS代码 start (一个网页只需插入一次) -->
<script type="text/javascript">
    /* * * CONFIGURATION VARIABLES * * */
    var disqus_shortname = "guanghuiwang";
    var disqus_identifier = "https://wghglory.github.io/2017/04/24/angular2-chapter06/";
    var disqus_url = "https://wghglory.github.io/2017/04/24/angular2-chapter06/";

    (function () {
        var dsq = document.createElement('script');
        dsq.type = 'text/javascript';
        dsq.async = true;
        dsq.src = '//' + disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    })();
</script>
<!-- disqus 公共JS代码 end -->



<!-- Footer -->
<!-- Footer -->
<footer>
    <div class="container">
        <div class="row">
            <div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1 text-center">
                <br>
                <ul class="list-inline text-center">
                
                
                

                

                
                <li>
                    <a target="_blank" href="https://www.jianshu.com/u/85d2cacc9fcd">
                                <span class="fa-stack fa-lg">
                                    <i class="fa fa-circle fa-stack-2x"></i>
                                    <i class="fa fa-stack-1x fa-inverse">简</i>
                                </span>
                    </a>
                </li>
                

                
                    <li>
                        <a target="_blank" href="https://www.facebook.com/wghglory">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-facebook fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
                

                
                    <li>
                        <a target="_blank"  href="https://github.com/wghglory">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-github fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
                

                
                    <li>
                        <a target="_blank"  href="https://www.linkedin.com/in/guanghuiwang">
                            <span class="fa-stack fa-lg">
                                <i class="fa fa-circle fa-stack-2x"></i>
                                <i class="fa fa-linkedin fa-stack-1x fa-inverse"></i>
                            </span>
                        </a>
                    </li>
                

                </ul>
                <p class="copyright text-muted">
                    Copyright &copy; Guanghui 2017
                    <br>
                    <span id="busuanzi_container_site_pv" style="font-size: 12px;">PV: <span id="busuanzi_value_site_pv"></span> Times</span>
                    <br>
                    Modified theme based on <a href="https://haojen.github.io/">Haojen Ma</a>' Anisina
                </p>

            </div>
        </div>
    </div>
</footer>

<!-- jQuery -->
<script src="/js/jquery.min.js"></script>

<!-- Bootstrap Core JavaScript -->
<script src="/js/bootstrap.min.js"></script>

<!-- Custom Theme JavaScript -->
<script src="/js/blog.js"></script>

<!-- code block fold/unfold button and copy button -->
<script src="/js/codeBlockEnhance.js"></script>

<!-- async load function -->
<script>
    function async(u, c) {
      var d = document, t = 'script',
          o = d.createElement(t),
          s = d.getElementsByTagName(t)[0];
      o.src = u;
      if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); }
      s.parentNode.insertBefore(o, s);
    }
</script>

<!-- jquery.tagcloud.js -->
<script>
    // only load tagcloud.js in tag.html
    if($('#tag_cloud').length !== 0){
        async("https://wghglory.github.io/js/jquery.tagcloud.js",function(){
            $.fn.tagcloud.defaults = {
                //size: {start: 1, end: 1, unit: 'em'},
                color: {start: '#bbbbee', end: '#0085a1'},
            };
            $('#tag_cloud a').tagcloud();
        })
    }
</script>

<!--fastClick.js -->
<script>
    async("//cdn.bootcss.com/fastclick/1.0.6/fastclick.min.js", function(){
        var $nav = document.querySelector("nav");
        if($nav) FastClick.attach($nav);
    })
</script>

<!-- Google Analytics -->


<script>
    // dynamic User by Hux
    var _gaId = 'UA-91771069-1';
    var _gaDomain = 'wghglory.github.io';
    // Originial
    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
                (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
            m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
    ga('create', _gaId, _gaDomain);
    ga('send', 'pageview');
</script>


<!-- Baidu Tongji -->


<!-- swiftype -->
<script type="text/javascript">
  // (function(w,d,t,u,n,s,e){w['SwiftypeObject']=n;w[n]=w[n]||function(){
  // (w[n].q=w[n].q||[]).push(arguments);};s=d.createElement(t);
  // e=d.getElementsByTagName(t)[0];s.async=1;s.src=u;e.parentNode.insertBefore(s,e);
  // })(window,document,'script','//s.swiftypecdn.com/install/v2/st.js','_st');
  //
  // _st('install','undefined','2.0.0');
</script>

<script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>

<!--wechat title img-->
<img class="wechat-title-img" src="/images/avatar.jpg">
</body>

</html>
